home *** CD-ROM | disk | FTP | other *** search
/ Qoole for Quake / Qoole for Quake (USA) / Qoole for Quake (USA).bin / Tutorial / HTML / QUBE.ZIP / SRC / ENTITIES.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-05  |  5.8 KB  |  280 lines

  1. /* entities.c */
  2.  
  3. #include "light.h"
  4.  
  5. entity_t    entities[MAX_MAP_ENTITIES];
  6. int            num_entities;
  7.  
  8. /*
  9. ==============================================================================
  10.  
  11. ENTITY FILE PARSING
  12.  
  13. If a light has a targetname, generate a unique style in the 32-63 range
  14. ==============================================================================
  15. */
  16.  
  17. int        numlighttargets;
  18. char    lighttargets[32][64];
  19.  
  20. int LightStyleForTargetname (char *targetname, qboolean alloc)
  21. {
  22.     int        i;
  23.     
  24.     for (i=0 ; i<numlighttargets ; i++)
  25.         if (!strcmp (lighttargets[i], targetname))
  26.             return 32 + i;
  27.     if (!alloc)
  28.         return -1;
  29.     strcpy (lighttargets[i], targetname);
  30.     numlighttargets++;
  31.     return numlighttargets-1 + 32;
  32. }
  33.  
  34.  
  35. /*
  36. ==================
  37. MatchTargets
  38. ==================
  39. */
  40. void MatchTargets (void)
  41. {
  42.     int        i,j;
  43.     
  44.     for (i=0 ; i<num_entities ; i++)
  45.     {
  46.         if (!entities[i].target[0])
  47.             continue;
  48.             
  49.         for (j=0 ; j<num_entities ; j++)
  50.             if (!strcmp(entities[j].targetname, entities[i].target))
  51.             {
  52.                 entities[i].targetent = &entities[j];
  53.                 break;
  54.             }
  55.         if (j==num_entities)
  56.         {
  57.             ShowWarningEntry("Warning:  Entity at (%i,%i,%i)",
  58.                 (int)entities[i].origin[0], (int)entities[i].origin[1],
  59.                 (int)entities[i].origin[2]);
  60.             ShowWarningEntry("(%s) has", entities[i].classname);
  61.             ShowWarningEntry("          unmatched target.");
  62.             sleep(1);
  63.                         continue;
  64.         }
  65.         
  66. /* set the style on the source ent for switchable lights */
  67.         if (entities[j].style)
  68.         {
  69.             char    s[16];
  70.             
  71.             entities[i].style = entities[j].style;
  72.             sprintf (s,"%i", entities[i].style);
  73.             SetKeyValue (&entities[i], "style", s);
  74.         }
  75.     }    
  76. }
  77.  
  78.  
  79. /*
  80. ==================
  81. LoadEntities
  82. ==================
  83. */
  84. void LoadEntities (void)
  85. {
  86.     char         *data;
  87.     entity_t    *entity;
  88.     char        key[64];    
  89.     epair_t        *epair;
  90.     
  91.     data = dentdata;
  92. /* */
  93. /* start parsing */
  94. /* */
  95.     num_entities = 0;
  96.     
  97. /* go through all the entities */
  98.     while (1)
  99.     {
  100.     /* parse the opening brace     */
  101.         data = COM_Parse (data);
  102.         if (!data)
  103.             break;
  104.         if (com_token[0] != '{')
  105.             Error ("LoadEntities: found %s when expecting {",com_token);
  106.  
  107.         if (num_entities == MAX_MAP_ENTITIES)
  108.             Error ("LoadEntities: MAX_MAP_ENTITIES");
  109.         entity = &entities[num_entities];
  110.         num_entities++;
  111.         
  112.     /* go through all the keys in this entity */
  113.         while (1)
  114.         {
  115.             int        c;
  116.  
  117.         /* parse key */
  118.             data = COM_Parse (data);
  119.             if (!data)
  120.                 Error ("LoadEntities: EOF without closing brace");
  121.             if (!strcmp(com_token,"}"))
  122.                 break;
  123.             strcpy (key, com_token);
  124.  
  125.         /* parse value */
  126.             data = COM_Parse (data);
  127.             if (!data)
  128.                 Error ("LoadEntities: EOF without closing brace");
  129.             c = com_token[0];
  130.             if (c == '}')
  131.                 Error ("LoadEntities: closing brace without data");
  132.             
  133.             epair = malloc (sizeof(epair_t));
  134.             memset (epair, 0, sizeof(epair));
  135.             strcpy (epair->key, key);
  136.             strcpy (epair->value, com_token);
  137.             epair->next = entity->epairs;
  138.             entity->epairs = epair;
  139.             
  140.             if (!strcmp(key, "classname"))
  141.                 strcpy (entity->classname, com_token);
  142.             else if (!strcmp(key, "target"))
  143.                 strcpy (entity->target, com_token);            
  144.             else if (!strcmp(key, "targetname"))
  145.                 strcpy (entity->targetname, com_token);
  146.             else if (!strcmp(key, "origin"))
  147.             {
  148.                 if (sscanf(com_token, "%lf %lf %lf",
  149.                         &entity->origin[0],
  150.                         &entity->origin[1],
  151.                         &entity->origin[2]) != 3)
  152.                     Error ("LoadEntities: not 3 values for origin");
  153.             }
  154.             else if (!strncmp(key, "light", 5))
  155.             {
  156.                 entity->light = atof(com_token);
  157.             }
  158.             else if (!strcmp(key, "style"))
  159.             {
  160.                 entity->style = atof(com_token);
  161.                 if ((unsigned)entity->style > 254)
  162.                     Error ("Bad light style %i (must be 0-254)", entity->style);
  163.             }
  164.             else if (!strcmp(key, "angle"))
  165.             {
  166.                 entity->angle = atof(com_token);
  167.             }
  168.         
  169.         }
  170.  
  171.     /* all fields have been parsed */
  172.         if (!strncmp (entity->classname, "light", 5) && !entity->light)
  173.             entity->light = DEFAULTLIGHTLEVEL;
  174.  
  175.         if (!strcmp (entity->classname, "light"))
  176.         {
  177.             if (entity->targetname[0] && !entity->style)
  178.             {
  179.                 char    s[16];
  180.                 
  181.                 entity->style = LightStyleForTargetname (entity->targetname, true);
  182.                 sprintf (s,"%i", entity->style);
  183.                 SetKeyValue (entity, "style", s);
  184.             }
  185.         }
  186.     }
  187.  
  188.     ShowTempEntry("%d entities read", num_entities);
  189.  
  190.     MatchTargets ();
  191. }
  192.  
  193. char     *ValueForKey (entity_t *ent, char *key)
  194. {
  195.     epair_t    *ep;
  196.     
  197.     for (ep=ent->epairs ; ep ; ep=ep->next)
  198.         if (!strcmp (ep->key, key) )
  199.             return ep->value;
  200.     return "";
  201. }
  202.  
  203. void     SetKeyValue (entity_t *ent, char *key, char *value)
  204. {
  205.     epair_t    *ep;
  206.     
  207.     for (ep=ent->epairs ; ep ; ep=ep->next)
  208.         if (!strcmp (ep->key, key) )
  209.         {
  210.             strcpy (ep->value, value);
  211.             return;
  212.         }
  213.     ep = malloc (sizeof(*ep));
  214.     ep->next = ent->epairs;
  215.     ent->epairs = ep;
  216.     strcpy (ep->key, key);
  217.     strcpy (ep->value, value);
  218. }
  219.  
  220. float    FloatForKey (entity_t *ent, char *key)
  221. {
  222.     char    *k;
  223.     
  224.     k = ValueForKey (ent, key);
  225.     return atof(k);
  226. }
  227.  
  228. void     GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
  229. {
  230.     char    *k;
  231.     
  232.     k = ValueForKey (ent, key);
  233.     sscanf (k, "%lf %lf %lf", &vec[0], &vec[1], &vec[2]);
  234. }
  235.  
  236.  
  237.  
  238. /*
  239. ================
  240. WriteEntitiesToString
  241. ================
  242. */
  243. void WriteEntitiesToString (void)
  244. {
  245.     char    *buf, *end;
  246.     epair_t    *ep;
  247.     char    line[128];
  248.     int        i;
  249.     
  250.     buf = dentdata;
  251.     end = buf;
  252.     *end = 0;
  253.     
  254.     ShowTempEntry("%i switchable light styles", numlighttargets);
  255.     
  256.     for (i=0 ; i<num_entities ; i++)
  257.     {
  258.         ep = entities[i].epairs;
  259.         if (!ep)
  260.             continue;    /* ent got removed */
  261.         
  262.         strcat (end,"{\n");
  263.         end += 2;
  264.                 
  265.         for (ep = entities[i].epairs ; ep ; ep=ep->next)
  266.         {
  267.             sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
  268.             strcat (end, line);
  269.             end += strlen(line);
  270.         }
  271.         strcat (end,"}\n");
  272.         end += 2;
  273.  
  274.         if (end > buf + MAX_MAP_ENTSTRING)
  275.             Error ("Entity text too long");
  276.     }
  277.     entdatasize = end - buf + 1;
  278. }
  279.  
  280.